#include "StdAfx.h"
#include "im_packet_impl.h"
#include "dll_object.h"
#include "sm_driver.h"

im_packet_impl::im_packet_impl()
{
	inet_pkt = NULL;
	event = 0;
	wparam = 0;
	lparam = 0;
	raw_body = new aot::tt::buffer_impl();
	sm_iid = -1;
	pkt_type = e_im_pkt_type_from_tata;

	memset(&header, 0, sizeof(header));
	memset(&date_time, 0, sizeof(date_time));

	header.version = aot::inet::PKT_VERSION;
	header.type = aot::inet::e_pkt_type_data;
}

im_packet_impl::~im_packet_impl()
{
	if( raw_body )
	{
		raw_body->destroy();
		raw_body = NULL;
	}
	if( inet_pkt )
	{
		inet_pkt->destroy();
		inet_pkt = NULL;
	}
}

bool 
im_packet_impl::clone(aot::im::iim_packet** out)
{
	im_packet_impl* p = new im_packet_impl;
	*out = (aot::im::iim_packet*)p;

	p->event = this->event;
	p->wparam = this->wparam;
	p->lparam = this->lparam;
	p->sm_iid = this->sm_iid;
	p->pkt_type = this->pkt_type;

	p->set_call_id(this->get_call_id());
	memcpy(&p->header, &this->header, sizeof(this->header));
	memcpy(&p->exh, &this->exh, sizeof(this->exh));

	if( this->raw_body && this->raw_body->length() > 0 )
	{
		p->raw_body->create(this->raw_body->length());
		p->raw_body->copy_from(this->raw_body->rd_ptr(), this->raw_body->length());
	}
	if( this->inet_pkt )
	{
		p->inet_pkt = this->inet_pkt->clone();
	}
	
	return true;
}

bool 
im_packet_impl::assign(aot::im::iim_packet* p)
{
	this->event = p->event;
	this->wparam = p->wparam;
	this->lparam = p->lparam;
	this->sm_iid = p->sm_iid;
	this->pkt_type = p->pkt_type;
	this->set_call_id(p->get_call_id());
	memcpy(&this->header, &p->header, sizeof(this->header));
	memcpy(&this->exh, &p->exh, sizeof(this->exh));

	this->raw_body->recycle();

	if( p->raw_body && p->raw_body->length() > 0 )
	{
		this->raw_body->enlarge_space(p->raw_body->length());
		this->raw_body->copy_from(p->raw_body->rd_ptr(), p->raw_body->length());
	}

	if( p->inet_pkt )
	{
		if( this->inet_pkt )
		{
			this->inet_pkt->destroy();
		}
		this->inet_pkt = p->inet_pkt->clone();
	}
	
	return true;
}

bool 
im_packet_impl::create_inet_pkt()
{
	if( this->inet_pkt )
	{
		this->inet_pkt->destroy();
		this->inet_pkt = NULL;
	}

	if( !g_dll_obj->query_interface_from_aot_inet_dll((void**)&this->inet_pkt, aot::inet::ipacket::iid) )
	{
		aot_log_error(AOT_LM_DEBUG, "create_inet_pkt() failed");
		return false;
	}
	return true;
}

aot::im::iim_packet* 
im_packet_impl::create_pkt()
{
	aot::im::iim_packet* p = new im_packet_impl;
	return p;
}

const char* 
im_packet_impl::get_call_id()
{
	return this->call_id_.c_str();
}

void 
im_packet_impl::set_call_id(const char* s)
{
	this->call_id_ = s;
}
